<?php

class Component extends Object {

	public $_loaded = array();


	public $_primary = array();


	public $__settings = array();


	public function init(&$controller,$action=null) {
	    if($action) {
		    $atcomponents= $action.'_components';
        }		
		if (!is_array($controller->components) && ( empty($action) || !isset($controller->{$atcomponents}) || !is_array($controller->{$atcomponents}) ) ) {
			return;
		}	
	    if($action && isset($controller->{$atcomponents}) && is_array($controller->{$atcomponents}) ) {
		    $controller->components =  array_merge($controller->{$atcomponents},$controller->components) ;
		}
		$this->_loadComponents($controller);
	}

	public function initialize(&$controller) {
		foreach (array_keys($this->_loaded) as $name) {
			$component =& $this->_loaded[$name];
			if (method_exists($component,'initialize') && $component->enabled === true) {
				$settings = array();
				if (isset($this->__settings[$name])) {
					$settings = $this->__settings[$name];
				}
				$component->initialize($controller, $settings);
			}
		}
	}

	public function startup(&$controller) {
		$this->triggerCallback('startup', $controller);
	}

	public function beforeRender(&$controller) {
		$this->triggerCallback('beforeRender', $controller);
	}

	public function beforeRedirect(&$controller, $url, $status = null, $exit = true) {
		$response = array();
		foreach ($this->_primary as $name) {
			$component =& $this->_loaded[$name];
			if ($component->enabled === true && method_exists($component, 'beforeRedirect')) {
				$resp = $component->beforeRedirect($controller, $url, $status, $exit);
				if ($resp === false) {
					return false;
				}
				$response[] = $resp;
			}
		}
		return $response;
	}

	public function shutdown(&$controller) {
		$this->triggerCallback('shutdown', $controller);
	}

	public function triggerCallback($callback, &$controller) {
		foreach ($this->_primary as $name) {
			$component =& $this->_loaded[$name];
			if (method_exists($component, $callback) && $component->enabled === true) {
				$component->{$callback}($controller);
			}
		}
	}

	public function _loadComponents(&$object, $parent = null) {	
		$normal = $object->components;
		foreach ((array)$normal as $component => $config) {
            if(is_int($component) && is_array($config) ) {
			    unset( $object->components[$component] );
                continue ;
			}		
            if(is_int($component) && is_string($config) ) {
			    $component = $config;
				$config = null ;
			}
			$componentCn = ucfirst($component) . 'Component';
			if (!class_exists($componentCn)) {
                Loader::import('components.'.$component);
			}
			if ($parent === null) {
				$this->_primary[] = $component;
			}
            $componentVar = 'C_' . $component;			
			if (isset($this->_loaded[$component])) {
				$object->{$componentVar} =& $this->_loaded[$component];
				if (!empty($config) && isset($this->__settings[$component])) {
					$this->__settings[$component] = array_merge($this->__settings[$component], $config);
				} elseif (!empty($config)) {
					$this->__settings[$component] = $config;
				}
			} else {
				$object->{$componentVar} =& new $componentCn();
				$object->{$componentVar}->enabled = true;
				$this->_loaded[$component] =& $object->{$componentVar};
				if (!empty($config)) {
					$this->__settings[$component] = $config;
				}
			}
			if (isset($object->{$componentVar}->components) && is_array($object->{$componentVar}->components) && (!isset($object->{$componentVar}->{$parent}))) {
				$this->_loadComponents($object->{$componentVar}, $componentVar);
			}			
		}
	}
}
